<template>
  <div class="overflow-x-hidden w-full">
    <div class="flex justify-between items-center py-4">
      <h2 class="text-2xl">
        <span class="text-primary">{{ course?.semester }}</span>
        <span class="text-xs">学年</span>
        <span class="text-secondary">{{ course?.term }}</span>
        <span class="text-xs">学期</span>
        <span class="mx-4">{{ course?.name }} - 实训报告</span>
      </h2>

      <div class="flex gap-2 mx-2">
        <ZButton
          icon-class="icon-[mdi--file-export]"
          color="secondary"
          size="sm"
          @click="refetch"
          :loading="isLoading"
        >
          刷新
        </ZButton>
        <ZButton
          icon-class="icon-[mdi--add]"
          color="primary"
          size="sm"
          @click="
            selected = undefined;
            reportShow = true;
          "
        >
          添加报告
        </ZButton>
      </div>
      <ZModal box-class="w-[80%]" v-model="reportShow">
        <h3>{{ selected ? "编辑" : "添加" }}报告</h3>
        <ReportForm
          :course-id="Number(id)"
          :init-values="selected"
          :serial="maxSerial"
          @success="reportShow = false"
        ></ReportForm>
      </ZModal>
    </div>

    <ZTable
      class="border rounded-box"
      :columns="columns"
      :data="results || []"
      key-name="id"
    >
      <template #date="{ row }">
        {{ formatDate(new Date(row.date), "YYYY-MM-DD") }}
      </template>
      <template #score="{ row }">
        <span
          :class="
            cn({
              'text-green-400': row.score >= 80,
              'text-blue-400': row.score < 80 && row.score >= 70,
              'text-red-400': row.score < 70,
            })
          "
        >
          {{ row.score }}
        </span>
      </template>
      <template #action="{ row }">
        <div class="flex gap-2">
          <ZButton
            icon-class="icon-[mdi--edit]"
            color="primary"
            size="sm"
            :disabled="row.score"
            @click="
              reportShow = true;
              selected = row;
            "
          >
            编辑
          </ZButton>
          <ZButton
            icon-class="icon-[mdi--file-export]"
            color="secondary"
            size="sm"
            :loading="exporting"
            @click="exportReport(row.id)"
          >
            导出
          </ZButton>
          <ZButton
            icon-class="icon-[mdi--delete]"
            color="error"
            size="sm"
            :disabled="row.score"
            @click="onDelete(row)"
          >
            删除
          </ZButton>
        </div>
      </template>
    </ZTable>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from "vue";

import ZTable, { type TableColumn } from "@/components/ui/ZTable.vue";
import ZButton from "@/components/ui/ZButton.vue";
import ZModal from "@/components/ui/ZModal.vue";
import ReportForm from "./components/ReportForm.vue";

import { type ApiResponse, type PaginationParams } from "@/apis";
import { findCourse } from "@/apis/course";
import * as api from "@/apis/report";
import type { Report } from "@/stores";
import { useMutation, useQuery, useQueryCache } from "@pinia/colada";
import { REPORT_QUERY_KEYS } from "@/query/report";
import { COURSE_QUERY_KEY } from "@/query/course";

import { formatDate } from "@vueuse/core";
import { downloadFile, cn } from "@/components/utils";

interface Props {
  id: string;
}

const props = defineProps<Props>();

// get course info
const { data: courseData } = useQuery({
  key: COURSE_QUERY_KEY.item(Number(props.id)),
  query: () => findCourse(Number(props.id)),
});
const course = computed(() => courseData.value?.object);
//
const reportShow = ref(false);

const columns: TableColumn[] = [
  {
    label: "报告序号",
    name: "serial",
  },
  {
    label: "报告日期",
    name: "date",
  },
  {
    label: "报告名称",
    name: "name",
  },
  {
    label: "分数",
    name: "score",
  },
  {
    label: "修改时间",
    name: "updatedAt",
    type: "datetime",
  },
  {
    label: "操作",
    name: "action",
  },
];

const selected = ref<Report>();
// const { isFetching, results, execute, count, page, pageSize } =
//   usePageFetch<Report>(`/course/${props.id}/reports`);

const pageParams = ref<PaginationParams>({
  page: 1,
  pageSize: 10,
});
const {
  isLoading,
  data: reportsData,
  refetch,
} = useQuery({
  key: REPORT_QUERY_KEYS.list(Number(props.id)),
  query: () => api.findCourseReports(Number(props.id), pageParams.value),
});
const results = computed(() => reportsData.value?.query.results || []);
const maxSerial = computed(() => {
  if (!results.value?.length) return 1;
  return Math.max(...results.value.map((i) => i.serial)) + 1;
});

const {
  data: response,
  mutate: exportReport,
  isLoading: exporting,
} = useMutation({
  mutation: api.exportReport,
});

watch(response, (value) => {
  if (value?.ok) {
    const contentDisposition = value?.headers.get("Content-Disposition");
    let filename = "实验报告.docx"; // 默认文件名
    if (contentDisposition) {
      // 解析 Content-Disposition 头
      const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
      const matches = filenameRegex.exec(contentDisposition);
      if (matches && matches[1]) {
        // 去除可能的引号并解码
        filename = matches[1].replace(/['"]/g, "");
        filename = decodeURIComponent(filename);
      }
    }
    downloadFile(
      value.data as Blob,
      filename,
      value.headers.get("Content-Type") || "application/octet-stream"
    );
  }
});

// 删除报告
const queryCache = useQueryCache();
const { mutate: delReport } = useMutation({
  mutation: api.deleteReport,
  onSuccess(data, vars) {
    const prev = queryCache.getQueryData<ApiResponse<Report>>(
      REPORT_QUERY_KEYS.list(Number(props.id))
    );
    if (data.success && prev) {
      queryCache.setQueryData(REPORT_QUERY_KEYS.list(Number(props.id)), {
        ...prev,
        query: {
          ...prev.query,
          count: prev.query.count - 1,
          results: prev.query.results.filter((i) => i.id !== vars),
        },
      });
      queryCache.invalidateQueries({
        key: REPORT_QUERY_KEYS.list(Number(props.id)),
      });
    }
  },
});
async function onDelete(row: Report) {
  if (confirm("确认删除吗？")) {
    delReport(row.id);
  }
}
</script>
